// Map 常见操作: size, set, get, has, delete, clear
// 遍历操作: keys(), values(), entries(), forEach()
// Map 和 Set 的遍历顺序就是插入顺序!!
const m = new Map()

// 增
m.set('a', 'aa')
m.set('b', 'bb')

// 删
m.delete('b')
// m.clear();

// 改
m.set('a', 'aaa')

//查
console.log(m.get('a'))

console.log(m)

// 遍历
const map = new Map([
    ['F', 'no'],
    ['T', 'yes'],
])

for (let key of map.keys()) {
    console.log(key)
}
// "F"
// "T"

for (let value of map.values()) {
    console.log(value)
}
// "no"
// "yes"

for (let item of map.entries()) {
    console.log(item[0], item[1])
}
// "F" "no"
// "T" "yes"

// 或者
for (let [key, value] of map.entries()) {
    console.log(key, value)
}
// "F" "no"
// "T" "yes"

// 等同于使用map.entries()
for (let [key, value] of map) {
    console.log(key, value)
}
// "F" "no"
// "T" "yes"

map.forEach(function (value, key, map) {
    console.log("Key: %s, Value: %s", key, value);
})

// 转换
// 1. Map 转为 数组
const myMap = new Map()
    .set(true, 7)
    .set({ foo: 3 }, ['abc']);
const myMaptoArr = [...myMap]
console.log(myMap, '转换之后的数组:', myMaptoArr)

// 2. 数组 转为 Map
// 将数组传入 Map 构造函数，就可以转为 Map
console.log(new Map([
    [true, 7],
    [{ foo: 3 }, ['abc']]
]))

// 3. Map 转为 对象
// 如果所有 Map 的键都是字符串，它可以无损地转为对象

function strMapToObj(strMap) {
    let obj = Object.create(null);
    for (let [k, v] of strMap) {
        obj[k] = v;
    }
    return obj;
}

const myNewMap = new Map()
    .set('yes', true)
    .set('no', false)
console.log(myNewMap, '转换的对象', strMapToObj(myNewMap))
// { yes: true, no: false }
// 如果有非字符串的键名，那么这个键名会被转成字符串，再作为对象的键名

// 4. 对象 转为 Map
// 对象转为 Map 可以通过Object.entries()

let obj = { "a": 1, "b": 2 };
let objtoMap = new Map(Object.entries(obj));
console.log(obj, '转换的Map', objtoMap)
// 此外，也可以自己实现一个转换函数。

function objToStrMap(obj) {
    let strMap = new Map();
    for (let k of Object.keys(obj)) {
        strMap.set(k, obj[k]);
    }
    return strMap;
}

console.log('转换为的Map', objToStrMap({ yes: true, no: false }))
// Map {"yes" => true, "no" => false}

// 5. Map 转为 JSON
// Map 转为 JSON 要区分两种情况。一种情况是，Map 的键名都是字符串，这时可以选择转为对象 JSON

function strMapToJson(strMap) {
    return JSON.stringify(strMapToObj(strMap));
}

let myJSONMap = new Map().set('yes', true).set('no', false);
console.log('Map 转 JSON', strMapToJson(myJSONMap))
// '{"yes":true,"no":false}'
// 另一种情况是，Map 的键名有非字符串，这时可以选择转为数组 JSON

function mapToArrayJson(map) {
    return JSON.stringify([...map]);
}

let myMapJSON = new Map().set(true, 7).set({ foo: 3 }, ['abc']);
console.log('Map 转 JSON', mapToArrayJson(myMapJSON))
// '[[true,7],[{"foo":3},["abc"]]]'

// 6. JSON 转为 Map
function jsonToStrMap(jsonStr) {
    return objToStrMap(JSON.parse(jsonStr));
}

console.log('JSON 转 Map', jsonToStrMap('{"yes": true, "no": false}'))
// Map {'yes' => true, 'no' => false}